<?php
# 文件名称:loader.php
defined( '_SYS' ) or die( 'No direct script access allowed' );
//加载类
class C_loader {
	var $_sys_ob_level;
	var $_sys_is_php5		= FALSE;
	var $_sys_is_instance 	= FALSE; // 判断初始化方式 $this 或者 $SYS =& get_instance()
	var $_sys_cached_vars	= array();
	var $_sys_classes		= array();
	var $_sys_loaded_files	= array();
	var $_sys_models		= array();
	var $_sys_views			= array();
	var $_sys_helpers		= array();
	var $_sys_plugins		= array();
	var $_messageQueue 		= array();
	
	/**
	 * 构造函数
	 * @访问限制	public
	 */
	function C_loader()
	{	
		$this->_sys_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;
		$this->_sys_ob_level  = ob_get_level();
	}
	
		
	/**
	 * 类加载函数(非继承于Object基类的自定义类加载) 加载控制类Controller会出错
	 * @访问限制	public
	 * @参数		string	类名
	 * @参数		mixed	可选参数
	 * @参数		string	可选对象名
	 * @返回类型	void
	 
	 */	
	function library($library = '', $params = NULL, $Object_name = NULL)
	{
		if ($library == '')
		{
			return FALSE;
		}
		if ( ! is_null($params) AND ! is_array($params))
		{
			$params = NULL;
		}
		if (is_array($library))
		{
			foreach ($library as $class)
			{
				$this->_sys_load_class($class, $params, $Object_name);
			}
		}
		else
		{
			$this->_sys_load_class($library, $params, $Object_name);
		}
		
		$this->_sys_assign_to_models();
	}
	/**
	 * 业务加载
	 * @访问限制	public
	 * @参数		string	类名
	 * @参数		string	业务名
	 * @参数		bool		数据库连接
	 * @返回类型	void
	 */	
	function model($model, $name = '', $db_conn = FALSE)
	{		
		if (is_array($model))
		{
			foreach($model as $babe)
			{
				$this->model($babe);	
			}
			return;
		}
		if ($model == '')
		{
			return;
		}
	
		//带路径的类名处理
		if (strpos($model, '/') === FALSE)
		{
			$path = '';
		}
		else
		{
			$x = explode('/', $model);
			$model = end($x);			
			unset($x[count($x)-1]);
			$path = implode('/', $x).'/';
		}
	
		if ($name == '')
		{
			$tmp=explode(".", $model);
			$name = $tmp[0].$tmp[1];
		}
		
		if (in_array($name, $this->_sys_models, TRUE))
		{
			return;
		}
		
		$SYS =& get_instance();
		if (isset($SYS->$name))
		{
			show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
		}
	
		$model = strtolower($model);
		
		if ( ! file_exists(PATH_BASE.DS.'models'.DS.$path.$model.EXT))
		{
			$SYS->$name=false;
			return;
		}
	
		if ( ! class_exists('C_model'))
		{
			_import('mvc/model', FALSE);
		}
		require_once(PATH_BASE.DS.'models'.DS.$path.$model.EXT);
		$tmp=explode(".", $model);
		$model = $tmp[0].$tmp[1];
		
		$model = ucfirst($model);
				
		$SYS->$name = new $model();
		//更新引用
		//$SYS->$name->_assign_libraries();
		//记录模型名称
		$this->_sys_models[] = $name;	
	}
	
	function view($view, $name = '')
	{		
		if (is_array($view))
		{
			foreach($view as $babe)
			{
				$this->view($babe);	
			}
			return;
		}
		if ($view == '')
		{
			return;
		}
	
		//带路径的类名处理
		if (strpos($view, '/') === FALSE)
		{
			$path = '';
		}
		else
		{
			$x = explode('/', $view);
			$view = end($x);			
			unset($x[count($x)-1]);
			$path = implode('/', $x).'/';
		}
		//解析文件名
		if ($name == '')
		{
			$tmp=explode(".", $view);
			$name = $tmp[0].$tmp[1];
		}
		
		if (in_array($name, $this->_sys_views, TRUE))
		{
			return;
		}
		
		$SYS =& get_instance();
		if (isset($SYS->$name))
		{
			show_error('The view name you are loading is the name of a resource that is already being used: '.$name);
		}
	
		$view = strtolower($view);
		if ( ! file_exists(PATH_BASE.DS.'views'.DS.$path.$view.EXT))
		{
			show_error('Unable to locate the view you have specified: '.$view);
		}
	
		if ( ! class_exists('C_view'))
		{
			_import('mvc/view', FALSE);
		}
		
		require_once(PATH_BASE.DS.'views'.DS.$path.$view.EXT);
		
		$tmp=explode(".", $view);
		$view = $tmp[0].$tmp[1];
		
		$view = ucfirst($view);
			
		$SYS->$name = new $view();
		//$SYS->$name->_assign_libraries();		
		$this->_sys_views[] = $name;
	}
	
	/**
	 * 数据库加载
	 *
	 * @访问限制	public
	 * @返回类型	Object
	 */	
	function &getDBO()
	{
		$SYS = &get_instance();
		$instance = $SYS->db;
		if (!is_object($instance))
		{			
			require_once(PATH_LIBRARIES.DS.'database'.DS.'mysql'.EXT);
        
			$opts = array(
						  'host'=>$SYS->config->item('host'),
						  'user'=>$SYS->config->item('user'),
						  'password'=>$SYS->config->item('password'),
						  'database'=>$SYS->config->item('db'),
						  'prefix'=>$SYS->config->item('dbprefix'),
						  'select'=>true
			
			);
			$SYS->db = new C_mysql($opts);
			$instance = $SYS->db;
		}
		return $instance;
		//$this->_sys_assign_to_models();
	}
	function &getDTO($table)
	{
		_import('database/table',false);
		$dto = &C_table::getInstance($table);		
		return $dto;
	}
	/**
	 * 辅助加载
	 * @访问限制	public
	 * @参数		mixed
	 * @返回类型	void
	 */
	function helper($helper)
	{				
		$helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');
		if (isset($this->_sys_helpers[$helper]))
		{
			return;
		}
		
		$base_helper = PATH_SITE.DS.'helpers/'.$helper.EXT;
		if (file_exists($base_helper))
		{				
			include_once($base_helper);
		}
		elseif (file_exists(PATH_ADMINISTRATOR.DS.'helpers/'.$helper.EXT))
		{ 
			include_once(PATH_ADMINISTRATOR.DS.'helpers/'.$helper.EXT);
		}
		else
		{		
			show_error('Unable to load the requested file: helpers/'.$helper.EXT);
		}
		$this->_sys_helpers[$helper] = TRUE;		
	}
	
	/**
	 * @访问限制	public
	 * @参数		array
	 * @返回类型	void
	 */
	function helpers($helpers = array())
	{
		if ( ! is_array($helpers))
		{
			$helpers = array($helpers);
		}
	
		foreach ($helpers as $helper)
		{
			$this->helper($helpers);
		}
	}
	
	/**
	 * 插件加载
	 * @访问限制	public
	 * @参数		array
	 * @返回类型	void
	 */
	function plugin($plugins = array())
	{
		if ( ! is_array($plugins))
		{
			$plugins = array($plugins);
		}
	
		foreach ($plugins as $plugin)
		{	
			$plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');		
			if (isset($this->_sys_plugins[$plugin]))
			{
				continue;
			}
			if (file_exists(PATH_ADMINISTRATOR.DS.'plugins/'.$plugin.EXT))
			{
				include_once(PATH_ADMINISTRATOR.DS.'plugins/'.$plugin.EXT);	
			}
			else
			{
				if (file_exists(PATH_ADMINISTRATOR.DS.'plugins/'.$plugin.EXT))
				{
					include_once(PATH_ADMINISTRATOR.DS.'plugins/'.$plugin.EXT);	
				}
				else
				{
					show_error('Unable to load the requested file: plugins/'.$plugin.EXT);
				}
			}
			
			$this->_sys_plugins[$plugin] = TRUE;
		}		
	}
	/**
	 * @访问限制	public
	 * @参数		array
	 * @返回类型	void
	 */
	function plugins($plugins = array())
	{
		$this->plugin($plugins);
	}
		
	/**
	 * 语言文件加载
	 * @访问限制	public
	 * @参数		array
	 * @参数		string
	 * @返回类型	void
	 */
	function language($file = array(), $lang = '')
	{
		$SYS =& get_instance();
		if ( ! is_array($file))
		{
			$file = array($file);
		}
		foreach ($file as $langfile)
		{	
			$SYS->lang->load($langfile, $lang);
		}
	}
	
	/**
	 * 内部类加载
	 *
	 * @访问限制	private
	 * @参数 		string
	 * @参数		mixed
	 * @参数		string
	 * @返回类型 	void
	 */
	function _sys_load_class($class, $params = NULL, $Object_name = NULL)
	{	
		$class = str_replace(EXT, '', trim($class, '/'));//  "/lib/test.php" => lib/test
		$subdir = '';
		if (strpos($class, '/') !== FALSE)
		{
			$x = explode('/', $class);	//解析
			
			$class = end($x);
			
			unset($x[count($x)-1]); //将最后一个变量即文件名变量注销
			
			$subdir = implode($x, '/').'/'; //合并
		}
		foreach (array(ucfirst($class), strtolower($class)) as $class)
		{
			$filepath = PATH_LIBRARIES.DS.$subdir.$class.EXT;
			if (file_exists($filepath))
			{
				if (in_array($filepath, $this->_sys_loaded_files))
				{
					if ( ! is_null($Object_name))
					{
						$SYS =& get_instance();
						if ( ! isset($SYS->$Object_name))
						{
							return $this->_sys_init_class($class, '', $params, $Object_name);			
						}
					}
					
					$is_duplicate = TRUE;
					return;
				}
				include_once($filepath);
				
				$this->_sys_loaded_files[] = $filepath;
	
				return $this->_sys_init_class($class, '', $params, $Object_name);			
			}
		
			$is_duplicate = FALSE;
		}
		if ($subdir == '')
		{
			$path = strtolower($class).DS.$class;
			return $this->_sys_load_class($path, $params);
		}
		
		if ($is_duplicate == FALSE)
		{
			show_error("Unable to load the requested class: ".$class);
		}
	}
	
	/**
	 * 类初始化
	 *
	 * @访问限制	private
	 * @参数		string
	 * @参数		string
	 * @参数		string
	 * @返回类型	null
	 */
	function _sys_init_class($class, $prefix = '', $config = FALSE, $Object_name = NULL)
	{		
		
		if ($prefix == '')
		{			
			if (class_exists('C_'.$class)) 
			{
				$name = 'C_'.$class;
			}
			else
			{
				$name = 'C_'.$class;
			}
		}
		else
		{
			$name = $prefix.$class;
		}
		// 类名是否已定义
		if ( ! class_exists($name))
		{
			show_error("Non-existent class: ".$class);
		}
		
		$class = strtolower($class);
		
		//对象名称管理
		if (is_null($Object_name))
		{
			$classvar = $class ;
		}
		else
		{
			$classvar = $Object_name;
		}
		$this->_sys_classes[$class] = $classvar;
		$SYS =& get_instance();
		if ($config !== NULL)
		{
			$SYS->$classvar = new $name($config);
		}
		else
		{		
			$SYS->$classvar = new $name;
		}	
	} 	
	
	/**
	 * 自动加载autoload.php -- 由控制类调用该函数
	 *
	 * @访问限制	private
	 * @参数		array
	 * @返回类型	void
	 */
	function _sys_autoloader()
	{	
		// 加载数据库驱动
		$classes = array(
							'config'	=> 'config',							
							'errors'	=> 'errors/exceptions',	
							'lang'		=> 'environment/language',
							'input'		=> 'environment/input',
							'uri'		=> 'environment/uri',
							'router'	=> 'environment/router',
							'request'	=> 'environment/request',
							'response'	=> 'environment/response',
							'html'		=> 'html/html',
							'doc'		=> 'html/document',
							'user'		=> 'user/user',
							'access'	=> 'user/access/access'
							);
		$SYS = &get_instance();		
		foreach ($classes as $var => $class)
		{
			$SYS->$var = &_import($class);
		}		
		$SYS->session = &_import('session/session',true,array('store'=>'database','expire'=>$SYS->config->item('lifetime')));
	}
	
	/**
	 * 添加到业务
	 *
	 * @访问限制	private
	 * @参数		Object
	 * @返回类型	array
	 */
	function _sys_assign_to_models()
	{
		
		if (count($this->_sys_models) == 0)
		{
			return;
		}
		
		if ($this->_sys_is_instance())
		{
			$SYS =& get_instance();
			foreach ($this->_sys_models as $model)
			{	
				$SYS->$model->_assign_libraries();
			}
			
		}
		else
		{		
			foreach ($this->_sys_models as $model)
			{			
				$this->$model->_assign_libraries();
			}
		}
	}  	
	/**
	 * 对象转换为数组
	 * @访问限制	private
	 * @参数		Object
	 * @返回类型	array
	 */
	function _sys_Object_to_array($Object)
	{
		return (is_Object($Object)) ? get_Object_vars($Object) : $Object;
	}
	function setMessage($msg, $type = 'message')
	{
		// Enqueue the message
		$this->_messageQueue[] = array('message' => $msg, 'type' => strtolower($type));
	}
	function getMessageQueue()
	{
		// Initialize variables
		$buffer	= null;
		$lists	= null;
		// Get the message queue
		$messages = $this->_messageQueue;
		// Build the sorted message list
		if (is_array($messages) && count($messages))
		{
			foreach ($messages as $msg)
			{
				if (isset($msg['type']) && isset($msg['message'])) {
					$lists[$msg['type']][] = $msg['message'];
				}
			}
		}
		// If messages exist render them
		if (is_array($lists))
		{
			// Build the return string
			$buffer .= "\n<dl id=\"system-message\">";
			foreach ($lists as $type => $msgs)
			{
				if (count($msgs))
				{
					$buffer .= "\n<dt class=\"".strtolower($type)."\">".C_text::_($type)."</dt>";
					$buffer .= "\n<dd class=\"".strtolower($type)." message fade\">";
					$buffer .= "\n\t<ul>";
					foreach ($msgs as $msg) {
						$buffer .="\n\t\t<li>".$msg."</li>";
					}
					$buffer .= "\n\t</ul>";
					$buffer .= "\n</dd>";
				}
			}
			$buffer .= "\n</dl>";
		}
		return $buffer;
	}
	
	function &load_class($class, $instantiate = TRUE, $options = NULL)
	{
		static $Objects = array();		
		$class = str_replace(EXT, '', trim($class, '/'));//  "/lib/test.php" => lib/test
		$subdir = '';
		if (strpos($class, '/') !== FALSE)
		{
			$x = explode('/', $class);	//解析
			
			$class = end($x);
			
			unset($x[count($x)-1]); //将最后一个变量即文件名变量注销
			
			$subdir = implode($x, '/').'/'; //合并
		}
		
		$filepath = PATH_LIBRARIES.DS.$subdir.$class.EXT;		
		
		$name = 'C_'.strtolower($class);
		// 是否存在
		if (isset($Objects[$name]))
		{
			return $Objects[$name];
		}
		
		if (file_exists($filepath))
		{
			require_once($filepath);
		}
		if ($instantiate == FALSE)
		{
			$Objects[$name] = TRUE;
			return $Objects[$name];
		}		
		if($options==NULL)	$Objects[$name] = new $name();
		else	$Objects[$name] = new $name($options);
		return $Objects[$name];
	}
}
//公共函数
if ( ! function_exists('_import'))
{
	function _import( $class, $instantiate = TRUE, $options = NULL ) {
		$ref = C_loader::load_class($class, $instantiate, $options);	
		return $ref;
	}
}
?>